/*
 * @Author: 0x9DEFA478
 * @Date: 2021-07-27 23:01:22
 * @LastEditTime: 2022-01-07 18:38:08
 * @LastEditors: 0x9DEFA478
 * @Description: 
 * QQ:2652450237
 * ============================================================================================================================================
 * 
 * 
 * 
 *                                                                                               ************      ****************************
 *                                                                                             ************      ****************************  
 *                                                                                           ************      ****************************    
 *                                                                                         ************      ****************************      
 *                                                                                       ************      ************                        
 *                                                                                     ************      ************                          
 *                                                                                   ************      ************                            
 *                                                                                 ************      ************                              
 *                                                                               ************      ************                                
 *                                                                             ************      ************                                  
 *                                                                           ************      ************                                    
 *                                                                         ************      ************                                      
 *                                                                       ************      ************                                        
 *                                                                     ************      ************                                          
 *                                                                   ************      ************                                            
 *                                                                 ************      ************                                              
 *                                                               ************      ************                                                
 *                                                             ************      ************                                                  
 *                                                           ************      ************                                                    
 *                                                         ************      ************                                                      
 *                                                       ************      ************                                                        
 *                                                     ************      ************                                                          
 *                                                   ************      ************                                                            
 *                                                 ************      ************                                                              
 *                                               ************      ************                                                                
 *                                             ************      ************                                                                  
 *                                           ************      ************                                                                    
 *                                         ************      ************                                                                      
 *                                       ************      ************                                                                        
 *                                     ************      ************                                                                          
 *                                   ************      ************                                                                            
 *                                 ************      ************                                                                              
 *                               ************      ************                                                                                
 *                             ************      ************                                                                                  
 *                           ************      ************                                                                                    
 *                         ************      ************                                                                                      
 *       ****************************      ************                                                                                        
 *     ****************************      ************                                                                                          
 *   ****************************      ************                                                                                            
 * ****************************      ************                                                                                              
 * 
 * 
 * 
 * ============================================================================================================================================
 * 
 */
#include "Peripheral.h"
#include "I_W25Q_DualBank.h"




static void Bootloader(void);

/**
 * @brief QuadSPI初始化
 * @return 无
 */
static void QuadSPI_DualBank_init(void);

/**
 * @brief 设置QuadSPI为内存映射模式
 * @return 无
 */
static void QuadSPI_SetMemoryMapped(void);




/**
 * @brief 系统预初始化 初始化QSPI 片外RAM等 在SystemInit中调用
 * @return 无
 */
void BspPreInit(){

  

  //跳转条件判断 如果满足跳转条件 下面的代码就不会执行
  Bootloader();

  

	SCB->VTOR=0x00000000U;//设置中断向量表

  //域 1 内核时钟配置寄存器
  RCC->D1CCIPR=(RCC->D1CCIPR&(~RCC_D1CCIPR_QSPISEL_Msk))|

    //QUADSPI 内核时钟源选择
    //0x0U：将 rcc_hclk3 时钟选作内核外设时钟（复位后的默认值）
    //0x1U：将 pll1_q_ck 时钟选作内核外设时钟
    //0x2U：将 pll2_r_ck 时钟选作内核外设时钟
    //0x3U：将 per_ck 时钟选作内核外设时钟
    (RCC_D1CCIPR_QSPISEL_Msk&(0x0U<<RCC_D1CCIPR_QSPISEL_Pos));
	

  //Qspi
  QuadSPI_DualBank_init();
  QuadSPI_SetMemoryMapped();
  __DSB();
  __ISB();
  
}

#define vBootLoader_DFUAddr 0x1FFF0000U

/**
 * @brief 跳转到DFU 跳转前请保证外设关闭妥当
 * @return 无
 */
void Bootloader_JumpDFU(){
  
  __set_MSP(((unsigned int *)vBootLoader_DFUAddr)[0]);
	__set_CONTROL(0);

  ((void (**)(void))vBootLoader_DFUAddr)[1]();

  for(;;){
  }
}


//应用程序基地址
#define vBootLoader_ApplicationAddr             (0x00000000U)

//跳转到应用程序 返回不为0 失败
static int Bootloader_JumpApplication(){
  Huint32 EntryAddr;

  //中断向量表由应用程序设置
  //SCB->VTOR=0x0U|0x0U;//设置中断向量表

  EntryAddr=((volatile Huint32 *)vBootLoader_ApplicationAddr)[1];

  //程序入口地址范围判定
  if(((EntryAddr>0x00000FFFFU)||(EntryAddr<0x00000004U))
  &&((EntryAddr<0x90000000U)||(EntryAddr>0x91FFFFFFU))){
    return -1;
  }

  __set_MSP(((volatile Huint32 *)vBootLoader_ApplicationAddr)[0]);
  __set_CONTROL(0);
  __ISB();

  ((void (**)(void))vBootLoader_ApplicationAddr)[1]();

  for(;;){
  }

}




static void Bootloader(){

  //加载ITCM代码
  // I_W25Q_DualBank_Init();
  // I_W25Q_DualBank_ReadData(0,(unsigned char *)0,64*1024);

  // __DSB();
  // __ISB();

  // Bootloader_JumpApplication();//跳转到应用程序
}




//================================================================================================================================================================
//
//        QuadSPI
//
//================================================================================================================================================================

#define QuadSPI_BK1CS_GPIOx			GPIOB
#define QuadSPI_BK1CS_PinNum		6



#define QuadSPI_SCK_GPIOx				GPIOB
#define QuadSPI_SCK_PinNum			2

#define QuadSPI_BK1IO0_GPIOx		GPIOD
#define QuadSPI_BK1IO0_PinNum		11

#define QuadSPI_BK1IO1_GPIOx		GPIOD
#define QuadSPI_BK1IO1_PinNum		12

#define QuadSPI_BK1IO2_GPIOx		GPIOE
#define QuadSPI_BK1IO2_PinNum		2

#define QuadSPI_BK1IO3_GPIOx		GPIOD
#define QuadSPI_BK1IO3_PinNum		13


//#define BK2CS_QuadSPI_GPIOx			
//#define BK2CS_QuadSPI_PinNum		

#define QuadSPI_BK2IO0_GPIOx		GPIOE
#define QuadSPI_BK2IO0_PinNum		7

#define QuadSPI_BK2IO1_GPIOx		GPIOE
#define QuadSPI_BK2IO1_PinNum		8

#define QuadSPI_BK2IO2_GPIOx		GPIOE
#define QuadSPI_BK2IO2_PinNum		9

#define QuadSPI_BK2IO3_GPIOx		GPIOE
#define QuadSPI_BK2IO3_PinNum		10

/**
 * @brief QuadSPI初始化
 * @return 无
 */
static void QuadSPI_DualBank_init(){

  RCC->AHB3ENR|=RCC_AHB3ENR_QSPIEN;
  RCC->AHB4ENR|=(RCC_AHB4ENR_GPIOBEN|RCC_AHB4ENR_GPIODEN|RCC_AHB4ENR_GPIOEEN|RCC_AHB4ENR_GPIOGEN|RCC_AHB4ENR_GPIOHEN);

  oIP_GPIO_Config(QuadSPI_SCK_GPIOx,    QuadSPI_SCK_PinNum,   vIP_GPIO_Mode_AF,vIP_GPIO_OutType_PP,vIP_GPIO_Speed_VERYHIGH,vIP_GPIO_PuPd_NP);

  oIP_GPIO_Config(QuadSPI_BK1CS_GPIOx,	QuadSPI_BK1CS_PinNum ,vIP_GPIO_Mode_AF,vIP_GPIO_OutType_PP,vIP_GPIO_Speed_VERYHIGH,vIP_GPIO_PuPd_NP);
  oIP_GPIO_Config(QuadSPI_BK1IO0_GPIOx,	QuadSPI_BK1IO0_PinNum,vIP_GPIO_Mode_AF,vIP_GPIO_OutType_PP,vIP_GPIO_Speed_VERYHIGH,vIP_GPIO_PuPd_NP);
  oIP_GPIO_Config(QuadSPI_BK1IO1_GPIOx,	QuadSPI_BK1IO1_PinNum,vIP_GPIO_Mode_AF,vIP_GPIO_OutType_PP,vIP_GPIO_Speed_VERYHIGH,vIP_GPIO_PuPd_NP);
  oIP_GPIO_Config(QuadSPI_BK1IO2_GPIOx,	QuadSPI_BK1IO2_PinNum,vIP_GPIO_Mode_AF,vIP_GPIO_OutType_PP,vIP_GPIO_Speed_VERYHIGH,vIP_GPIO_PuPd_NP);
  oIP_GPIO_Config(QuadSPI_BK1IO3_GPIOx,	QuadSPI_BK1IO3_PinNum,vIP_GPIO_Mode_AF,vIP_GPIO_OutType_PP,vIP_GPIO_Speed_VERYHIGH,vIP_GPIO_PuPd_NP);

  oIP_GPIO_Config(QuadSPI_BK2IO0_GPIOx,	QuadSPI_BK2IO0_PinNum,vIP_GPIO_Mode_AF,vIP_GPIO_OutType_PP,vIP_GPIO_Speed_VERYHIGH,vIP_GPIO_PuPd_NP);
  oIP_GPIO_Config(QuadSPI_BK2IO1_GPIOx,	QuadSPI_BK2IO1_PinNum,vIP_GPIO_Mode_AF,vIP_GPIO_OutType_PP,vIP_GPIO_Speed_VERYHIGH,vIP_GPIO_PuPd_NP);
  oIP_GPIO_Config(QuadSPI_BK2IO2_GPIOx,	QuadSPI_BK2IO2_PinNum,vIP_GPIO_Mode_AF,vIP_GPIO_OutType_PP,vIP_GPIO_Speed_VERYHIGH,vIP_GPIO_PuPd_NP);
  oIP_GPIO_Config(QuadSPI_BK2IO3_GPIOx,	QuadSPI_BK2IO3_PinNum,vIP_GPIO_Mode_AF,vIP_GPIO_OutType_PP,vIP_GPIO_Speed_VERYHIGH,vIP_GPIO_PuPd_NP);


  oIP_GPIO_SetAF(QuadSPI_SCK_GPIOx,		QuadSPI_SCK_PinNum,	 9U);

  oIP_GPIO_SetAF(QuadSPI_BK1CS_GPIOx,	QuadSPI_BK1CS_PinNum,10U);
  oIP_GPIO_SetAF(QuadSPI_BK1IO0_GPIOx,QuadSPI_BK1IO0_PinNum,9U);
  oIP_GPIO_SetAF(QuadSPI_BK1IO1_GPIOx,QuadSPI_BK1IO1_PinNum,9U);
  oIP_GPIO_SetAF(QuadSPI_BK1IO2_GPIOx,QuadSPI_BK1IO2_PinNum,9U);
  oIP_GPIO_SetAF(QuadSPI_BK1IO3_GPIOx,QuadSPI_BK1IO3_PinNum,9U);

  oIP_GPIO_SetAF(QuadSPI_BK2IO0_GPIOx,QuadSPI_BK2IO0_PinNum,10U);
  oIP_GPIO_SetAF(QuadSPI_BK2IO1_GPIOx,QuadSPI_BK2IO1_PinNum,10U);
  oIP_GPIO_SetAF(QuadSPI_BK2IO2_GPIOx,QuadSPI_BK2IO2_PinNum,10U);
  oIP_GPIO_SetAF(QuadSPI_BK2IO3_GPIOx,QuadSPI_BK2IO3_PinNum,10U);



  QUADSPI->CR=0;

  QUADSPI->CR|=((2U-1U)<<QUADSPI_CR_PRESCALER_Pos)    //设置分频 2分频
    |((4U-1U)<<QUADSPI_CR_FTHRES_Pos)                 //设置FIFO阈值为4
    |(0x0U<<QUADSPI_CR_FSEL_Pos)                      //设置bank bank(x+1)
    |(0x1U<<QUADSPI_CR_DFM_Pos)                       //双闪存模式
    |(0x0U<<QUADSPI_CR_SSHIFT_Pos)                    //延迟采样
    |(0x0U<<QUADSPI_CR_TCEN_Pos);                     //超时定时器是否使能

  QUADSPI->DCR=(24U<<QUADSPI_DCR_FSIZE_Pos)           //设置寻址大小 2^(x+1) 字节   25:64MB 20:2MB
    |((2U-1U)<<QUADSPI_DCR_CSHT_Pos)                  //设置cs最小高电平时间
    |(0<<QUADSPI_DCR_CKMODE_Pos);                     //设置mode0 空闲低电平

  QUADSPI->CR|=QUADSPI_CR_EN;//使能QUADSPI

}




/**
 * @brief 设置QuadSPI为内存映射模式
 * @return 无
 */
static void QuadSPI_SetMemoryMapped(){

  //设置交替字节
  QUADSPI->ABR=0xFFFFFFFFU;

  //DataMode
  //0：无数据
  //1：单线传输数据
  //2：双线传输数据
  //3：四线传输数据

  //DummyCycles空闲时钟数

  //AlternateBytesSize
  //0：8 位交替字节
  //1：16 位交替字节
  //2：24 位交替字节
  //3：32 位交替字节

  //AlternateByteMode
  //0：无交替字节
  //1：单线传输交替字节
  //2：双线传输交替字节
  //3：四线传输交替字节

  //AddressSize
  //0：8 位地址
  //1：16 位地址
  //2：24 位地址
  //3：32 位地址

  //AddressMode
  //0：无地址
  //1：单线传输地址
  //2：双线传输地址
  //3：四线传输地址

  //CMDMode
  //0：无指令
  //1：单线传输指令
  //2：双线传输指令
  //3：四线传输指令

  QUADSPI->CCR=(0<<QUADSPI_CCR_DDRM_Pos)
    |(0<<QUADSPI_CCR_SIOO_Pos)
    |(QUADSPI_CCR_DMODE_Msk         &(0x03U <<QUADSPI_CCR_DMODE_Pos))         //DataMode
    |(QUADSPI_CCR_DCYC_Msk          &(0x04U <<QUADSPI_CCR_DCYC_Pos))          //DummyCycles
    |(QUADSPI_CCR_ABSIZE_Msk        &(0x00U <<QUADSPI_CCR_ABSIZE_Pos))        //AlternateBytesSize
    |(QUADSPI_CCR_ABMODE_Msk        &(0x03U <<QUADSPI_CCR_ABMODE_Pos))        //AlternateByteMode
    |(QUADSPI_CCR_ADSIZE_Msk        &(0x02U <<QUADSPI_CCR_ADSIZE_Pos))        //AddressSize
    |(QUADSPI_CCR_ADMODE_Msk        &(0x03U <<QUADSPI_CCR_ADMODE_Pos))        //AddressMode
    |(QUADSPI_CCR_IMODE_Msk         &(0x01U <<QUADSPI_CCR_IMODE_Pos))         //CMDMode
    |(QUADSPI_CCR_INSTRUCTION_Msk   &(0xEBU <<QUADSPI_CCR_INSTRUCTION_Pos))   //CMD
    |(QUADSPI_CCR_FMODE_Msk         &(0x03U <<QUADSPI_CCR_FMODE_Pos));        //0:间接写入模式 1:间接读取模式 2:自动轮询模式 3:内存映射模式
                                                                      

}



